package com.itfreer.gis.data.file;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.kabeja.dxf.DXFConstants;
import org.kabeja.dxf.DXFDocument;
import org.kabeja.dxf.DXFLWPolyline;
import org.kabeja.dxf.DXFLayer;
import org.kabeja.dxf.DXFVertex;
import org.kabeja.dxf.helpers.Point;
import org.kabeja.parser.Parser;
import org.kabeja.parser.ParserBuilder;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LinearRing;
import org.locationtech.jts.geom.Polygon;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.NoSuchAuthorityCodeException;
import org.springframework.stereotype.Component;

/**
 * CAD dxf文件分析
 */
@Component
public class CadFileDataEditServerImp implements CadFileDataEditServer {

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public List<SimpleFeature> queryFeature(String filePath, String where) throws Exception {
		List<SimpleFeature> resultLst = new ArrayList<SimpleFeature>();
		Parser parser = ParserBuilder.createDefaultParser();
		parser.parse(filePath);
		DXFDocument doc = parser.getDocument();
		Iterator in = doc.getDXFLayerIterator();
		List<Coordinate> points = new ArrayList<Coordinate>();
		
		while (in.hasNext()) {
			DXFLayer layer = (DXFLayer) in.next();
			// 1、读取多边形对象
			List<DXFLWPolyline> lst = layer.getDXFEntities(DXFConstants.ENTITY_TYPE_LWPOLYLINE);
			if (lst != null && lst.size() > 0) {
				for (int index = 0; index < lst.size(); index++) {
					// 这里需要处理掉是否闭合，闭合的采用面要素，非闭合的采用线要素
					// （闭合分两种情况，1、闭合的集合元素，如矩形，2、首位两个点坐标的一样的元素）
					DXFLWPolyline line = lst.get(index);
					Iterator vertexs = line.getVertexIterator();
					while (vertexs.hasNext()) {
						DXFVertex vertex = (DXFVertex) vertexs.next();
						Point point = vertex.getPoint();
						points.add(new Coordinate(point.getX(), point.getY()));
					}
					SimpleFeature f = createFeature(points, index);
					if (f != null) {
						resultLst.add(f);
					}
				}
			}

			// 2、读取线对象
//			List<DXFLine> lstLine = layer.getDXFEntities(DXFConstants.ENTITY_TYPE_LINE);
//			if (lstLine != null && lstLine.size() > 0) {
//				for (int index = 0; index < lstLine.size(); index++) {
//					DXFLine line = (DXFLine) lstLine.get(index);
//					LineFeature gisLine = new LineFeature();
//					// 简单的线处理
//					Point spoint = line.getStartPoint();
//					PointFeature gisSPoint = new PointFeature();
//					gisSPoint.setX(spoint.getX());
//					gisSPoint.setY(spoint.getY());
//					gisSPoint.setZ(spoint.getZ());
//					gisLine.addPoint(gisSPoint);
//					// 简单的线处理
//					Point epoint = line.getEndPoint();
//					PointFeature gisEPoint = new PointFeature();
//					gisEPoint.setX(epoint.getX());
//					gisEPoint.setY(epoint.getY());
//					gisEPoint.setZ(epoint.getZ());
//					gisLine.addPoint(gisEPoint);
//					
//					
//					resultLst.add(gisLine);
//				}
//			}

			// 3、读取圆对象
//			List<DXFCircle> lstCircle = layer.getDXFEntities(DXFConstants.ENTITY_TYPE_CIRCLE);
//			if (lstCircle != null && lstCircle.size() > 0) {
//				for (int index = 0; index < lstCircle.size(); index++) {
//					DXFCircle circle = (DXFCircle) lstCircle.get(index);
//					CircleFeature circleFeature = new CircleFeature();
//					Point cpoint = circle.getCenterPoint();
//					PointFeature gissPoint = new PointFeature();
//					gissPoint.setX(cpoint.getX());
//					gissPoint.setY(cpoint.getY());
//					gissPoint.setZ(cpoint.getZ());
//					circleFeature.setCenter(gissPoint);
//					circleFeature.setRadius(circle.getRadius());
//					resultLst.add(circleFeature);
//				}
//			}
		}
		System.out.println("结束");
		return resultLst;
	}
	
	private static SimpleFeature createFeature(List<Coordinate> points, int k)
			throws NoSuchAuthorityCodeException, FactoryException {
		// 一个点以内，不处理
		if (points.size() <= 1) {
			points.clear();
			return null;
		}
		// 检查最后一个点和第一个点是否一样
		Coordinate one = points.get(0);
		Coordinate last = points.get(points.size() - 1);
		if (one.getX() != last.getX() || one.getY() != last.getY()) {
			points.add(new Coordinate(one.getX(), one.getY()));
		}
		// 二个点以内，不处理
		if (points.size() <= 2) {
			points.clear();
			return null;
		}
		Coordinate[] ps = new Coordinate[points.size()];
		ps = points.toArray(ps);
		points.clear();
		return createFeature(ps, k);
	}

	private static SimpleFeature createFeature(Coordinate[] coords, Integer i)
			throws NoSuchAuthorityCodeException, FactoryException {
		GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
		LinearRing ring = geometryFactory.createLinearRing(coords);
		LinearRing holes[] = null; // use LinearRing[] to represent holes
		Polygon polygon = geometryFactory.createPolygon(ring, holes);

		SimpleFeatureType type = createFeatureType();
		// create the builder
		SimpleFeatureBuilder builder = new SimpleFeatureBuilder(type);
		// add the values
		builder.add(polygon);
		// build the feature with provided ID
		SimpleFeature feature = builder.buildFeature("fid." + i.toString());
		return feature;
	}

	private static SimpleFeatureType createFeatureType() throws NoSuchAuthorityCodeException, FactoryException {
		// 定义图形信息和属性信息
		SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
		// CoordinateReferenceSystem crs = DefaultGeographicCRS.WGS84;
		// tb.setCRS(crs);
		tb.setName("shapefile");
		tb.add("the_geom", Polygon.class);
		// build the type
		final SimpleFeatureType ftype = tb.buildFeatureType();
		return ftype;
	}

	/**
	 * 查询
	 * @return
	 */
	@Override
	public List<SimpleFeature> queryFeature(String source, String option, Geometry geometry) throws Exception {
		return null;
	}
	
	@Override
	public Boolean addFeatures(String source, List<SimpleFeature> datas, SimpleFeatureType metadata)
			throws IOException, NoSuchAuthorityCodeException, FactoryException {
		return false;
	}

	@Override
	public SimpleFeature updateFeature(String source, SimpleFeature row, SimpleFeatureType metadata) {
		return row;
	}

	@Override
	public Boolean deleteFeature(String source, String where) throws Exception {
		return false;
	}

	@Override
	public SimpleFeatureType getTableMetadata(String tableName) {
		return null;
	}
}
